<?php 
    class WZ_Model
    {
        public function __call($method, $args)
        {
            $methodCalled = substr($method, 0, 3);
            if ($methodCalled == 'get') {
                $uncamelizeMethod = \WZ_Inflector::uncamelize(lcfirst(substr($method, 3)));
                $var = \WZ_Inflector::lower($uncamelizeMethod);
                if (isset($this->$var)) {
                    return $this->$var;
                }
                return null;
            } elseif ($methodCalled == 'set') {
                $vars = array_keys(get_class_vars(get_class($this)));
                $value = $args[0];
                $uncamelizeMethod = \WZ_Inflector::uncamelize(lcfirst(substr($method, 3)));
                $var = \WZ_Inflector::lower($uncamelizeMethod);
                if (in_array($var, $vars)) {
                    $this->$var = $value;
                } else {
                    throw new \WZ_Exception("Unknown var $var in " . get_class($this) . " class.");
                }
            }
        }
        
        public function toArray()
        {
            $data = array();
            $vars = get_object_vars($this);
            foreach ($vars as $key => $value) {
                $data[$key] = $value;
            }
            return $data;
        }
        
        public function setFromArray(array $data)
        {
            $vars = get_object_vars($this);
            foreach ($data as $key => $value) {
                $key = \WZ_Inflector::lower(\WZ_Inflector::uncamelize(lcfirst($key)));
                if (in_array($key, $vars)) {
                    $this->$key = $value;
                }
            }
            return $this;
        }
        
        public function save()
        {
            $class = get_class($this);
            $serviceClass = str_replace('WZModel_', 'WZService_', $class);
            $serviceClass::init();
            $db = \Loader::WZ_Activerecord(new $class);
            $primary = $db->getPrimary();
            $vars = get_object_vars($this);
            $update = false;
            $data = array();
            foreach ($vars as $key => $value) {
                if ($key == $primary && null !== $value) {
                    $update = true;
                    $identity = $value;
                } else {
                    $data[$key] = $value;
                }
            }
            if (true === $update) {
                $db->update($data, "$primary = '$identity'");
                return $serviceClass::find($identity);
            } else {
                $newId = $db->insert($data);
                return $serviceClass::find($newId);
            }
        }
        
        public function delete()
        {
            $class = get_class($this);
            $db = \Loader::WZ_Activerecord(new $class);
            $primary = $db->getPrimary();
            $vars = get_object_vars($this);
            $delete = false;
            unset($vars['WZDbTable']);
            foreach ($vars as $key => $value) {
                if ($key == $primary && null !== $value) {
                    $delete = true;
                    $identity = $value;
                    break;
                }
            }
            if (true === $delete) {
                return $db->delete("$primary = '$identity'");
            }
            return false;
        }
        
        public function __toString()
        {
            return get_class($this);
        }
        
        public function TableName()
        {
            $class = get_class($this);
            return \WZ_Inflector::lower(\WZ_Inflector::clean(end(explode('_', $class))));
        }
        
        public function getId()
        {
            $class = get_class($this);
            $db = \Loader::WZ_Activerecord(new $class);
            $primary = $db->getPrimary();
            return $this->$primary;
        }
    }